<template>
  <div class="workflow-editor">
    <!-- 工具栏 -->
    <div class="toolbar">
      <div class="toolbar-left">
        <el-button type="primary" @click="handleSave" :loading="saving">
          <el-icon><Check /></el-icon>
          保存
        </el-button>
        <el-button @click="handlePreview">
          <el-icon><View /></el-icon>
          预览
        </el-button>
        <el-button @click="handleClear">
          <el-icon><Delete /></el-icon>
          清空
        </el-button>
      </div>
      <div class="toolbar-right">
        <el-button @click="handleZoomIn">
          <el-icon><ZoomIn /></el-icon>
          放大
        </el-button>
        <el-button @click="handleZoomOut">
          <el-icon><ZoomOut /></el-icon>
          缩小
        </el-button>
        <el-button @click="handleFit">
          <el-icon><FullScreen /></el-icon>
          适应
        </el-button>
      </div>
    </div>

    <!-- 节点面板 -->
    <div class="node-panel">
      <div class="panel-title">节点库</div>
      <div class="node-list">
        <div 
          v-for="node in nodeTypes" 
          :key="node.type"
          class="node-item"
          :draggable="true"
          @dragstart="handleDragStart($event, node)"
        >
          <div class="node-icon" :class="`node-${node.type}`">
            <el-icon>
              <component :is="node.icon" />
            </el-icon>
          </div>
          <div class="node-label">{{ node.label }}</div>
        </div>
      </div>
    </div>

    <!-- 画布区域 -->
    <div class="canvas-container">
      <div ref="containerRef" class="logicflow-container"></div>
    </div>

    <!-- 属性面板 -->
    <div class="property-panel" v-if="selectedNode">
      <div class="panel-title">属性设置</div>
      <el-form :model="nodeProperties" label-width="80px" size="small">
        <el-form-item label="节点名称">
          <el-input v-model="nodeProperties.name" @change="handlePropertyChange" />
        </el-form-item>
        <el-form-item label="节点类型">
          <el-input v-model="nodeProperties.type" disabled />
        </el-form-item>
        <el-form-item label="X坐标">
          <el-input-number v-model="nodeProperties.x" @change="handlePropertyChange" />
        </el-form-item>
        <el-form-item label="Y坐标">
          <el-input-number v-model="nodeProperties.y" @change="handlePropertyChange" />
        </el-form-item>
        <el-form-item label="宽度">
          <el-input-number v-model="nodeProperties.width" @change="handlePropertyChange" />
        </el-form-item>
        <el-form-item label="高度">
          <el-input-number v-model="nodeProperties.height" @change="handlePropertyChange" />
        </el-form-item>
        <!-- 根据节点类型显示不同属性 -->
        <template v-if="nodeProperties.type === 'userTask'">
          <el-form-item label="审批人">
            <el-input v-model="nodeProperties.assignee" @change="handlePropertyChange" />
          </el-form-item>
          <el-form-item label="审批组">
            <el-input v-model="nodeProperties.group" @change="handlePropertyChange" />
          </el-form-item>
        </template>
        <template v-if="nodeProperties.type === 'serviceTask'">
          <el-form-item label="服务地址">
            <el-input v-model="nodeProperties.serviceUrl" @change="handlePropertyChange" />
          </el-form-item>
          <el-form-item label="方法">
            <el-select v-model="nodeProperties.method" @change="handlePropertyChange">
              <el-option label="GET" value="GET" />
              <el-option label="POST" value="POST" />
              <el-option label="PUT" value="PUT" />
              <el-option label="DELETE" value="DELETE" />
            </el-select>
          </el-form-item>
        </template>
        <template v-if="nodeProperties.type === 'gateway'">
          <el-form-item label="网关类型">
            <el-select v-model="nodeProperties.gatewayType" @change="handlePropertyChange">
              <el-option label="排他网关" value="exclusive" />
              <el-option label="并行网关" value="parallel" />
              <el-option label="包容网关" value="inclusive" />
            </el-select>
          </el-form-item>
        </template>
      </el-form>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, nextTick } from 'vue';
import { ElMessage } from 'element-plus';
import { 
  Check, 
  View, 
  Delete, 
  ZoomIn, 
  ZoomOut, 
  FullScreen,
  Play,
  CircleCheck,
  User,
  Setting,
  Switch
} from '@element-plus/icons-vue';
import LogicFlow from '@logicflow/core';
import '@logicflow/core/dist/style/index.css';
import { 
  getWorkflowGraphData, 
  saveWorkflowGraphData 
} from '@/api/workflow';
import type { WorkflowGraphData, WorkflowNode, WorkflowEdge } from '@/api/workflow/WorkflowModel';

// Props
const props = defineProps<{
  workflowId: number;
}>();

// Emits
const emit = defineEmits<{
  save: [];
  close: [];
}>();

// 响应式数据
const containerRef = ref<HTMLElement>();
const lf = ref<LogicFlow>();
const saving = ref(false);
const selectedNode = ref<WorkflowNode | null>(null);

// 节点类型配置
const nodeTypes = [
  { type: 'start', label: '开始', icon: Play },
  { type: 'end', label: '结束', icon: CircleCheck },
  { type: 'userTask', label: '用户任务', icon: User },
  { type: 'serviceTask', label: '服务任务', icon: Setting },
  { type: 'gateway', label: '网关', icon: Switch }
];

// 节点属性
const nodeProperties = reactive({
  id: '',
  type: '',
  name: '',
  x: 0,
  y: 0,
  width: 100,
  height: 50,
  assignee: '',
  group: '',
  serviceUrl: '',
  method: 'POST',
  gatewayType: 'exclusive'
});

// 初始化LogicFlow
const initLogicFlow = () => {
  if (!containerRef.value) return;

  lf.value = new LogicFlow({
    container: containerRef.value,
    grid: true,
    keyboard: true,
    style: {
      rect: {
        rx: 5,
        ry: 5,
        strokeWidth: 2
      },
      circle: {
        r: 20,
        strokeWidth: 2
      },
      diamond: {
        rx: 10,
        ry: 10,
        strokeWidth: 2
      }
    },
    plugins: []
  });

  // 注册自定义节点
  registerCustomNodes();

  // 绑定事件
  bindEvents();

  // 加载数据
  loadWorkflowData();
};

// 注册自定义节点
const registerCustomNodes = () => {
  if (!lf.value) return;

  // 开始节点
  lf.value.register({
    type: 'start',
    view: 'circle',
    model: 'circle',
    text: '开始',
    properties: {
      name: '开始',
      type: 'start'
    }
  });

  // 结束节点
  lf.value.register({
    type: 'end',
    view: 'circle',
    model: 'circle',
    text: '结束',
    properties: {
      name: '结束',
      type: 'end'
    }
  });

  // 用户任务节点
  lf.value.register({
    type: 'userTask',
    view: 'rect',
    model: 'rect',
    text: '用户任务',
    properties: {
      name: '用户任务',
      type: 'userTask',
      assignee: '',
      group: ''
    }
  });

  // 服务任务节点
  lf.value.register({
    type: 'serviceTask',
    view: 'rect',
    model: 'rect',
    text: '服务任务',
    properties: {
      name: '服务任务',
      type: 'serviceTask',
      serviceUrl: '',
      method: 'POST'
    }
  });

  // 网关节点
  lf.value.register({
    type: 'gateway',
    view: 'diamond',
    model: 'diamond',
    text: '网关',
    properties: {
      name: '网关',
      type: 'gateway',
      gatewayType: 'exclusive'
    }
  });
};

// 绑定事件
const bindEvents = () => {
  if (!lf.value) return;

  // 节点选择事件
  lf.value.on('node:click', (data) => {
    const node = data.data;
    selectedNode.value = node;
    updateNodeProperties(node);
  });

  // 画布点击事件
  lf.value.on('blank:click', () => {
    selectedNode.value = null;
  });

  // 节点拖拽事件
  lf.value.on('node:drag', (data) => {
    const node = data.data;
    nodeProperties.x = node.x;
    nodeProperties.y = node.y;
  });
};

// 更新节点属性
const updateNodeProperties = (node: WorkflowNode) => {
  Object.assign(nodeProperties, {
    id: node.id,
    type: node.type,
    name: node.name,
    x: node.x,
    y: node.y,
    width: node.properties?.width || 100,
    height: node.properties?.height || 50,
    assignee: node.properties?.assignee || '',
    group: node.properties?.group || '',
    serviceUrl: node.properties?.serviceUrl || '',
    method: node.properties?.method || 'POST',
    gatewayType: node.properties?.gatewayType || 'exclusive'
  });
};

// 属性变化处理
const handlePropertyChange = () => {
  if (!lf.value || !selectedNode.value) return;

  const nodeData = lf.value.getNodeModelById(selectedNode.value.id);
  if (nodeData) {
    nodeData.updateText(nodeProperties.name);
    nodeData.setProperties({
      ...nodeData.properties,
      name: nodeProperties.name,
      assignee: nodeProperties.assignee,
      group: nodeProperties.group,
      serviceUrl: nodeProperties.serviceUrl,
      method: nodeProperties.method,
      gatewayType: nodeProperties.gatewayType,
      width: nodeProperties.width,
      height: nodeProperties.height
    });
  }
};

// 拖拽开始
const handleDragStart = (event: DragEvent, node: any) => {
  if (event.dataTransfer) {
    event.dataTransfer.setData('application/json', JSON.stringify(node));
  }
};

// 加载工作流数据
const loadWorkflowData = async () => {
  try {
    const response = await getWorkflowGraphData(props.workflowId);
    const graphData = response.data;
    
    if (graphData && lf.value) {
      lf.value.render(graphData);
    }
  } catch (error) {
    ElMessage.error('加载工作流数据失败');
  }
};

// 保存工作流
const handleSave = async () => {
  if (!lf.value) return;

  try {
    saving.value = true;
    const graphData = lf.value.getGraphData();
    
    await saveWorkflowGraphData(props.workflowId, graphData);
    ElMessage.success('保存成功');
    emit('save');
  } catch (error) {
    ElMessage.error('保存失败');
  } finally {
    saving.value = false;
  }
};

// 预览
const handlePreview = () => {
  if (!lf.value) return;
  
  const graphData = lf.value.getGraphData();
  console.log('工作流数据:', graphData);
  ElMessage.info('预览数据已输出到控制台');
};

// 清空
const handleClear = () => {
  if (!lf.value) return;
  
  lf.value.clearData();
  selectedNode.value = null;
};

// 放大
const handleZoomIn = () => {
  if (!lf.value) return;
  lf.value.zoom(true);
};

// 缩小
const handleZoomOut = () => {
  if (!lf.value) return;
  lf.value.zoom(false);
};

// 适应
const handleFit = () => {
  if (!lf.value) return;
  lf.value.fitView();
};

// 生命周期
onMounted(() => {
  nextTick(() => {
    initLogicFlow();
  });
});

onUnmounted(() => {
  if (lf.value) {
    lf.value.destroy();
  }
});
</script>

<style scoped>
.workflow-editor {
  display: flex;
  height: 100%;
  background: #f5f5f5;
}

.toolbar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 50px;
  background: white;
  border-bottom: 1px solid #e4e7ed;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
  z-index: 1000;
}

.toolbar-left,
.toolbar-right {
  display: flex;
  gap: 8px;
}

.node-panel {
  width: 200px;
  background: white;
  border-right: 1px solid #e4e7ed;
  margin-top: 50px;
  height: calc(100% - 50px);
  overflow-y: auto;
}

.panel-title {
  padding: 16px;
  font-weight: bold;
  border-bottom: 1px solid #e4e7ed;
  background: #fafafa;
}

.node-list {
  padding: 16px;
}

.node-item {
  display: flex;
  align-items: center;
  padding: 8px;
  margin-bottom: 8px;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  cursor: grab;
  background: white;
  transition: all 0.3s;
}

.node-item:hover {
  border-color: #409eff;
  box-shadow: 0 2px 4px rgba(64, 158, 255, 0.2);
}

.node-item:active {
  cursor: grabbing;
}

.node-icon {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  margin-right: 8px;
  color: white;
  font-size: 16px;
}

.node-start {
  background: #67c23a;
}

.node-end {
  background: #f56c6c;
}

.node-userTask {
  background: #409eff;
}

.node-serviceTask {
  background: #e6a23c;
}

.node-gateway {
  background: #909399;
}

.node-label {
  font-size: 14px;
  color: #303133;
}

.canvas-container {
  flex: 1;
  margin-top: 50px;
  position: relative;
}

.logicflow-container {
  width: 100%;
  height: 100%;
  background: white;
}

.property-panel {
  width: 300px;
  background: white;
  border-left: 1px solid #e4e7ed;
  margin-top: 50px;
  height: calc(100% - 50px);
  overflow-y: auto;
}

.property-panel .el-form {
  padding: 16px;
}

.property-panel .el-form-item {
  margin-bottom: 16px;
}
</style>

